package org.god.batis.core;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.Map;

public class SqlSession {
    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    public int insert(String sqlId, Object pojo) throws Exception {
        int count = 0;
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        String sql = sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();
        //sql中#{dsaf}需要替换为?
        //insert into wangzhong_car(id, car_num, brand, guide_price, produce_time, car_type) values (null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType})
        //insert into wangzhong_car(id, car_num, brand, guide_price, produce_time, car_type) values (null, ?, ?, ?, ?, ?)
        String newSql = sql.replaceAll("#\\{[0-9A-Za-z$]*}", "?");
        PreparedStatement ps = connection.prepareStatement(newSql);
        //怎么传值呢？#{}，大括号里面时属性名。已知对象，已知属性名。获取属性值(通过反射)
        int fromIndex = 0;
        int index = 1;//问好的下标
        while (true) {
            int jinghaoIndex = sql.indexOf("#", fromIndex);
            if (jinghaoIndex < 0) {
                break;
            }

            int youkuohaoIndex = sql.indexOf("}", fromIndex);
            String propertyName = sql.substring(fromIndex + 2, youkuohaoIndex).trim();
            fromIndex = youkuohaoIndex + 1;
            String getMethodName = "get" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
            Method declaredMethod = pojo.getClass().getDeclaredMethod(getMethodName);
            Object propertyValue = declaredMethod.invoke(pojo);
            //只支持字符串。需要别的数据类型，可以通过变量，获取变量的类型Fild的类型
            ps.setString(index, propertyValue.toString());
            index++;

        }
        ps.setString(1, pojo.toString());
        count = ps.executeUpdate();
        return count;
    }

    public Object selectOne(String sqlId, Object obj) throws SQLException {
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        Map<String, MappedStatement> mappedStatementMap = sqlSessionFactory.getMappedStatementMap();
        MappedStatement mappedStatement = mappedStatementMap.get(sqlId);
        String sql = mappedStatement.getSql();
        String resultType = mappedStatement.getResultType();
        try {
            String newSql = sql.replaceAll("#\\{[0-9A-Za-z$]*}", "?");
            PreparedStatement ps = connection.prepareStatement(newSql);
            //假设只有一个参数，并且是字符串.多个参数，仿照insert方法即可
            ps.setString(1, obj.toString());
            ResultSet resultSet = ps.executeQuery();
            if (resultSet.next()) {
                Class<?> aClass = Class.forName(resultType);
                Object o = aClass.newInstance();
                ResultSetMetaData rsmd = resultSet.getMetaData();
                int columnCount = rsmd.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    //列名，就是属性名。如果有下划线，则根据下划线分割，首字母大写，拼接上"set"构成set方法名
                    String propertyName = rsmd.getColumnName(i);
                    String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
                    Method declaredMethod = aClass.getDeclaredMethod(setMethodName, String.class);
                    declaredMethod.invoke(o, resultSet.getString(propertyName));
                    return o;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void commit() {
        sqlSessionFactory.getTransaction().commit();
    }

    public void rollback() {
        sqlSessionFactory.getTransaction().rollback();
    }

    public void close() {
        sqlSessionFactory.getTransaction().close();
    }
}
